package com.jdd.modules.parkmonthly.util;

import com.jdd.common.util.DateUtils;
import com.jdd.modules.parkmonthly.entity.enums.FileType;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * 文件工具类
 * <p>
 *
 * @package
 * @作者 zjf
 * @时间 2017年5月23日
 * @版本 1.0
 */
public class FileUtil {

	private static Logger log = LoggerFactory.getLogger(FileUtil.class);

	/** 默认文件路径 */
	public static final String FILE_PATH= "/secms/upload/YYYY/MM/";

	/** 默认日期格式 */
	public static final String FORMAT_DATE = "yyyy-MM-dd";

	/** 默认时间格式 */
	public static final String FORMAT_TIME = "HH:mm:ss";

	/** 默认日期时间格式 */
	public static final String FORMAT_DATETIME = "yyyyMMddHHmmss";

	public static final DateFormat format = new SimpleDateFormat(FORMAT_DATETIME);

    /**
     * 将path中的 YYYY替换为真实年份， MM替换为真实月份 path = “/secms/upload/YYYY/MM/”
     *
     * @return
     */
    public static String getFilePath() {
    	Date date = new Date();
		int year = DateUtils.getYear(date);
		int month = DateUtils.getMonth(date);
		return FILE_PATH.replace("YYYY", String.valueOf(year)).replace("MM", String.valueOf(month));
    }

    /**
     * 将YYYY替换为真实年份， MM替换为真实月份 path = “/secms/upload/YYYY/MM/”
     * upload 替换为path
     * @return
     */
    public static String getFilePath(String path) {
        Date date = new Date();
        int year = DateUtils.getYear(date);
        int month = DateUtils.getMonth(date);
        return FILE_PATH.replace("upload", path).replace("YYYY", String.valueOf(year)).replace("MM", String.valueOf(month));
    }


    private static String getTempPath() {
        Date date = new Date();
        int year = DateUtils.getYear(date);
        int month = DateUtils.getMonth(date);
        int day = DateUtils.getDay(date);
        int minute = DateUtils.getMinute(date);
        return "/secms/temp/YYYY/MM/DD/minute/".replace("YYYY", String.valueOf(year)).replace("MM", String.valueOf(month))
                .replace("DD", String.valueOf(day)).replace("minute", String.valueOf(minute));
    }

    public static String getFileNameAndCreateTempPath(String mainFileName) {
        String path = getTempPath();
        creatDirs(path);
        String result = path + getFileNameByRandom(mainFileName);
        if (new File(result).exists()) {
            return getFileNameAndCreateTempPath(mainFileName);
        }
        return result;
    }

    private static boolean creatDirs(String path) {
        File myPath = new File(path);
        if (myPath.exists()) {
            return true;
        } else {
            return myPath.mkdirs();
        }
    }

    /**
     * 下载文件
     *
     * @Title:download
     * @date 2017年12月12日
     * @author chin
     */
    public static void downloadToClient(HttpServletResponse response, String originalName, StreamWriterIntf writer) {
        ServletOutputStream outputStream = null;
        try {
            String realFileName = java.net.URLEncoder.encode(originalName.replace(" ", ""), "UTF-8");
            response.reset();
            response.setContentType("application/x-download");
            response.setHeader("Content-Disposition", "attachment;filename=\"" + new String(realFileName.getBytes("UTF-8"), "ISO8859_1"));

            outputStream = response.getOutputStream();
            writer.write(outputStream);
            outputStream.close();
        } catch (IOException e) {
            log.error("保存文件失败!");
            e.printStackTrace();
        } catch (Exception e) {
            log.error("保存文件失败!");
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static interface StreamWriterIntf {
        public void write(java.io.OutputStream stream) throws Exception;
    }

    public static void downloadFromExcel(HttpServletResponse response, Workbook workbook, String originalName) {


        downloadToClient(response, originalName, new StreamWriterIntf() {
            @Override
            public void write(java.io.OutputStream stream) throws Exception {
                workbook.write(stream);
                stream.close();
                if (workbook instanceof SXSSFWorkbook) {
                    ((SXSSFWorkbook) workbook).dispose();
                }

            }
        });
    }


    /**
     * 用当前时间+N位随机数
     *
     * @param @return
     * @return String
     * @Title:getFileNameByRandom
     * @date 2017年6月2日
     */
    public static String getFileNameByRandom(String flieName) {
		//  转换为字符串
		String formatDate = format.format(new Date());
		//  随机生成文件编号
		int random = new Random().nextInt(10000);
		return new StringBuffer().append(formatDate).append(random).append(flieName).toString();
	}
    /**
     * 获取文件保存的真实路径
    * @Title:getRealFilePath
    * @param @return
    * @return String
    * @date 2017年6月2日
     */
    public static String getRealFilePath(String flieName) {
    	return getFilePath()+getFileNameByRandom(flieName);
    }
    public static String getRealFilePath(String flieName,String dir) {
        return getFilePath(dir)+getFileNameByRandom(flieName);
    }
    /**
     * 下载文件
    * @Title:download
    * @date 2017年6月12日
    * @author jin
     */
    public static void download(HttpServletResponse response,String filePath, String originalName){
        FileInputStream inputStream = null;
        ServletOutputStream outputStream = null;
        try {
            String realFileName = java.net.URLEncoder.encode(originalName.replace(" ", ""), "UTF-8");
            inputStream = new FileInputStream(filePath);
            response.reset();
            response.setContentType("application/x-download");
            response.setHeader("Content-Disposition", "attachment;filename=\"" + new String(realFileName.getBytes("UTF-8"), "ISO8859_1"));

            outputStream = response.getOutputStream();
            byte[] b = new byte[1024];
            int i = 0;

            while ((i = inputStream.read(b)) > 0) {
                outputStream.write(b, 0, i);
            }

            inputStream.close();
            outputStream.close();
        }
        catch (FileNotFoundException e) {
        	log.error("文件无法找到:"+filePath);
            e.printStackTrace();
        }
        catch (IOException e) {
        	log.error("下载文件失败:"+filePath);
            e.printStackTrace();
        }
        catch (Exception e) {
        	log.error("下载文件失败:"+filePath);
            e.printStackTrace();
        }
        finally{
            if(inputStream!=null){
                try {
                    inputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(outputStream!=null){
                try {
                    outputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * @param @param response
     * @param @param request
     * @param @param filePath
     * @param @param originalName    设定文件
     * @return void    返回类型
     * @throws
     * @Title: download
     * @Description: 文件下载
     */
    public static void download(HttpServletResponse response,HttpServletRequest request, String filePath, String originalName){
        FileInputStream inputStream = null;
        ServletOutputStream outputStream = null;
        try {
            //ie浏览器处理中午
            if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
                originalName = URLEncoder.encode(originalName, "UTF-8");
            } else {
                originalName = new String(originalName.getBytes("UTF-8"), "ISO8859-1");
            }
            inputStream = new FileInputStream(filePath);
            response.reset();
            response.setContentType("application/x-download");
            response.setHeader("Content-Disposition", "attachment;filename=\"" + originalName);

            outputStream = response.getOutputStream();
            byte[] b = new byte[1024];
            int i = 0;

            while ((i = inputStream.read(b)) > 0) {
                outputStream.write(b, 0, i);
            }

            inputStream.close();
            outputStream.close();
        } catch (FileNotFoundException e) {
            log.error("文件无法找到!");
            e.printStackTrace();
        } catch (IOException e) {
            log.error("保存文件失败!");
            e.printStackTrace();
        } catch (Exception e) {
            log.error("保存文件失败!");
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(outputStream!=null){
                try {
                    outputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 得到文件后缀名
     *
     * @param fileName
     * @return
     */
    public static String getFileExt(String fileName) {
        if (fileName == null) {
            return "";
        }

        String ext = "";
        int lastIndex = fileName.lastIndexOf(".");
        if (lastIndex >= 0) {
            ext = fileName.substring(lastIndex + 1).toLowerCase();
        }
        return ext;
    }

    public static String getFileName(String fileName) {
        if (fileName == null) {
            return "";
        }
        int lastIndex = fileName.lastIndexOf(".");
        if (lastIndex == -1) {
            log.error("文件没有后缀名");
        }
        return fileName.substring(0, lastIndex);
    }

    /**
     * 将文件头转换成16进制字符串
     *
     * @param src 原生byte
     * @return 16进制字符串
     */
    private static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * 得到文件头
     *
     * @param is
     * @return 文件头
     * @throws IOException
     */
    private static String getFileContent(InputStream is) throws IOException {
        byte[] b = new byte[28];
        InputStream inputStream = null;
        try {
            is.read(b, 0, 28);
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    throw e;
                }
            }
        }
        return bytesToHexString(b);
    }

    /**
     * 获取文件类型类
     *
     * @param is
     * @return 文件类型
     */
    public static FileType getType(InputStream is) throws IOException {
        String fileHead = getFileContent(is);
        if (fileHead == null || fileHead.length() == 0) {
            return null;
        }
        fileHead = fileHead.toUpperCase();
        FileType[] fileTypes = FileType.values();
        for (FileType type : fileTypes) {
            if (fileHead.startsWith(type.getValue())) {
                return type;
            }
        }
        return null;
    }

    /**
     * 获取文件类型
     *
     * @param is
     * @return
     * @throws Exception
     */
    public static String getFileType(InputStream is) throws Exception {
        FileType fileType = getType(is);
        if (fileType != null) {
            return fileType.getValue();
        }
        return null;
    }

    /**
     * MultipartFile 转 file
     *
     * @param file
     * @return
     */
    public static File multipartFileToFile(MultipartFile file) throws Exception {
        InputStream in = file.getInputStream();
        File toFile = new File(file.getOriginalFilename());
        inputStreamToFile(in, toFile);
        in.close();
        return toFile;
    }

    /**
     * 获取文件流
     *
     * @param in
     * @param file
     * @throws Exception
     */
    public static void inputStreamToFile(InputStream in, File file) throws Exception {
        OutputStream out = new FileOutputStream(file);
        int bytesRead = 0;
        int len = 2048;
        byte[] buffer = new byte[2048];
        while ((bytesRead = in.read(buffer, 0, len)) != -1) {
            out.write(buffer, 0, bytesRead);
        }
        out.close();
        in.close();
    }

    /**
     * 删除本地临时文件
     *
     * @param file
     */
    public static void delteTempFile(File file) {
        if (file != null) {
            File del = new File(file.toURI());
            del.delete();
        }
    }

}

